package com.aiinterview.subjectservice.service.impl;


import cn.hutool.core.bean.BeanUtil;
import com.aiinterview.common.context.BaseContext;
import com.aiinterview.common.entity.PageResult;
import com.aiinterview.model.subject.dto.SubjetQueryDto;
import com.aiinterview.model.subject.entity.SubjectInfo;
import com.aiinterview.model.subject.vo.SubjectInfoListVo;
import com.aiinterview.model.subject.vo.SubjectInfoVo;
import com.aiinterview.subjectservice.mapper.SubjectInfoDao;
import com.aiinterview.subjectservice.service.SubjectInfoService;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

import static com.aiinterview.common.constant.RedisKey.USER_SUBJECT_FAVORITE_KEY;

/**
 * 题目信息表(SubjectInfo)表服务实现类
 *
 * @author makejava
 * @since 2025-01-06 14:13:23
 */
@Service("subjectInfoService")
@Slf4j
public class SubjectInfoServiceImpl implements SubjectInfoService {
    @Resource
    private SubjectInfoDao subjectInfoDao;

    private final String Like_Key = "subject:liked";
    private final String Favorited_Key = "subject:favorited";

    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    /**
     * 通过ID查询单条数据
     *
     * @param id 主键
     * @return 实例对象
     */
    @Override
    public SubjectInfo queryById(Long id) {
        return this.subjectInfoDao.queryById(id);
    }



    /**
     * 新增数据
     *
     * @param subjectInfo 实例对象
     * @return 实例对象
     */
    @Override
    public SubjectInfo insert(SubjectInfo subjectInfo) {
        this.subjectInfoDao.insert(subjectInfo);
        return subjectInfo;
    }

    /**
     * 修改数据
     *
     * @param subjectInfo 实例对象
     * @return 实例对象
     */
    @Override
    public SubjectInfo update(SubjectInfo subjectInfo) {
        this.subjectInfoDao.update(subjectInfo);
        return this.queryById(subjectInfo.getId());
    }

    /**
     * 通过主键删除数据
     *
     * @param id 主键
     * @return 是否成功
     */
    @Override
    public boolean deleteById(Long id) {
        return this.subjectInfoDao.deleteById(id) > 0;
    }

    /**
     * 根据条件进行分页查询
     * @param subjetQueryDto  删选结果
     * @return
     */
    @Override
    public PageResult pageQuery(SubjetQueryDto subjetQueryDto) {
        log.info("subjetQueryDto:{}", subjetQueryDto);
        PageHelper.startPage(subjetQueryDto.getPageIndex(), subjetQueryDto.getPageSize());
        Page<SubjectInfo> page = subjectInfoDao.pageQuery(subjetQueryDto);
        List<SubjectInfoListVo> result = new ArrayList<>();
        String []diff = new String[]{"简单","中等","困难"};
        // 将查询出的所有标签转换为VO返回给前端
        page.getResult().forEach(item -> {
            SubjectInfoListVo subjectInfoListVo = new SubjectInfoListVo();
            subjectInfoListVo.setSubjectId(String.valueOf(item.getId()));
            subjectInfoListVo.setSubjectName(item.getSubjectName());
            subjectInfoListVo.setSubjectDifficulty(diff[item.getSubjectDifficult()]);
            subjectInfoListVo.setSubjectLabelNames(item.getTags());
            result.add(subjectInfoListVo);
        });
        return new PageResult(page.getTotal(), result);
    }

    /**
     * 根据id获取题目信息
     * @param id
     * @return
     */
    @Override
    public SubjectInfoVo getInfoById(long id) {
        // 根据ID查询数据库中的SubjectInfo对象
        SubjectInfo subjectInfo = subjectInfoDao.queryById(id);

        // 创建一个新的SubjectInfoVo对象，用于展示层
        SubjectInfoVo subjectInfoVo = new SubjectInfoVo();

        // 使用BeanUtil工具类将SubjectInfo对象的属性复制到SubjectInfoVo对象中
        BeanUtil.copyProperties(subjectInfo, subjectInfoVo);

        // 设置SubjectInfoVo对象的标签，直接使用SubjectInfo对象的标签属性
        subjectInfoVo.setTags(subjectInfo.getTags());

        // 记录日志，输出根据ID获取的题目信息
        log.debug("根据id获取题目信息，subjectInfoVo:{}", subjectInfoVo);

        // 设置SubjectInfoVo对象的是否喜欢状态，通过调用isLiked方法判断
        subjectInfoVo.setIsLiked(isLiked(id));

        // 设置SubjectInfoVo对象的是否收藏状态，通过调用isFavorited方法判断
        subjectInfoVo.setIsFavorited(isFavorited(id));
        return subjectInfoVo;
    }

    /**
     * 点赞
     * @param subjectId
     */
    @Override
    public String like(long subjectId) {
        // 现在ThreadLocal存储了当前用户ID，所以直接获取即可
        long userId = BaseContext.getCurrentId();
        // 拼装KEY
        String key = Like_Key+ subjectId;
        int count = 1;
        // 判断该用户是否已经点赞过了
        if (!isLiked(subjectId)) {
            subjectInfoDao.updateLikeCount(subjectId,count);
            //  如果没点赞过 将用户ID添加到Redis集合中
            stringRedisTemplate.opsForSet().add(key, String.valueOf(userId));
            return "点赞成功";
        }else{
            count = -1;
            subjectInfoDao.updateLikeCount(subjectId,count);
            // 点赞过去，从Redis集合中移除用户ID
            stringRedisTemplate.opsForSet().remove(key, String.valueOf(userId));
            return "取消点赞成功";
        }
    }

    // 判断该题目是否被用户点赞
    public boolean isLiked(long subjectId) {
        // 现在ThreadLocal存储了当前用户ID，所以直接获取即可
        long userId = BaseContext.getCurrentId();
        // 拼装KEY
        String key = Like_Key+ subjectId;
        // 在判断该用户是否已经点赞过了
        Boolean isli = stringRedisTemplate.opsForSet().isMember(key, String.valueOf(userId));
        log.info("用户 ID {}, 用户是否点过赞", isli);
        return isli;
    }

    // 判断该题目是否被用户收藏
    public boolean isFavorited(long subjectId) {
        // 现在ThreadLocal存储了当前用户ID，所以直接获取即可
        long userId = BaseContext.getCurrentId();
        // 拼装KEY
        String key = Favorited_Key+ subjectId;

        // 判断是否收藏
        Boolean isli = stringRedisTemplate.opsForSet().isMember(key, String.valueOf(userId));
        return isli;
    }

    /**
     * 收藏
     * @param subjectId
     */
    @Override
    public String favorite(long subjectId) {
        // 现在ThreadLocal存储了当前用户ID，所以直接获取即可
        long userId = BaseContext.getCurrentId();
        // 拼装KEY
        String key = Favorited_Key+ subjectId;
        int count = 1;
        // 判断该用户是否已经点赞过了
        if (!isFavorited(subjectId)) {
            subjectInfoDao.updateFavoriteCount(subjectId,count);
            //  如果没点赞过 将用户ID添加到Redis集合中
            stringRedisTemplate.opsForSet().add(key, String.valueOf(userId));
            // 在用户收藏题目时，将该题目的ID添加到用户收藏的题目集合中
            stringRedisTemplate.opsForSet().add(USER_SUBJECT_FAVORITE_KEY+userId, String.valueOf(subjectId));
            return "收藏成功";
        }else{
            count = -1;
            subjectInfoDao.updateFavoriteCount(subjectId,count);
            // 点赞过去，从Redis集合中移除用户ID
            stringRedisTemplate.opsForSet().remove(key, String.valueOf(userId));
            // 从用户收藏的题目集合中移除该题目的ID
            stringRedisTemplate.opsForSet().remove(USER_SUBJECT_FAVORITE_KEY+userId, String.valueOf(subjectId));
            return "取消收藏成功";
        }
    }
}
